use std::any::type_name_of_val;

fn main() {
    println!("Hello, world!");

    let mut x = 1u128;
    println!("x is {}", x);
    x = 2;
    println!("x is {}", x);
    let i = u128::MAX;
    println!("i is {}", i);
    // loop {
    //     println!("x is {}", x);
    //     x *= 2;
    //     if x == 0 {
    //         break;
    //     }
    // }
    let mut a = (1, "hello");
    println!("a.0 is {}", a.0);
    println!("a.1 is {}", a.1);
    a.1 = "world";
    println!("a.1 is {}", a.1);

    let (x, y) = a;
    println!("x is {}", x);
    println!("y is {}", y);
    let n = type_name_of_val(&x);
    println!("type of x is {}", n);

    let mut i = 0;
    let res = loop {
        i += 1;
        if i == 10 {
            break i * 2;
        }
    };
    println!("res is {}", res);

    // 相互转换摄氏与华氏温度。
    let fahrenheit = celsius_to_fahrenheit(37.0);
    println!("37.0 Celsius is {} Fahrenheit", fahrenheit);
    let celsius = fahrenheit_to_celsius(98.6);
    println!("98.6 Fahrenheit is {} Celsius", celsius);
    // 生成第 n 个斐波那契数。
    for n in 0..=10 {
        let fib = fibonacci(n);
        println!("fibonacci({}) is {}", n, fib);
    }
    // 打印圣诞颂歌 “The Twelve Days of Christmas” 的歌词，并利用歌曲中的重复部分（编写循环）
    print_christmas_lyrics();

    // 实现了 Copy trait 的类型
    // 所有整数类型，比如 u32。
    // 布尔类型，bool，它的值是 true 和 false。
    // 所有浮点数类型，比如 f64。
    // 字符类型，char。
    // 元组，当且仅当其包含的类型也都实现 Copy 的时候。比如，(i32, i32) 实现了 Copy，但 (i32, String) 就没有。
}

fn print_christmas_lyrics() {
    let days = [
        "first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth",
        "tenth", "eleventh", "twelfth",
    ];

    let gifts = [
        "a partridge in a pear tree",
        "two turtle doves",
        "three French hens",
        "four calling birds",
        "five golden rings",
        "six geese a-laying",
        "seven swans a-swimming",
        "eight maids a-milking",
        "nine ladies dancing",
        "ten lords a-leaping",
        "eleven pipers piping",
        "twelve drummers drumming",
    ];

    for day in 0..12 {
        println!(
            "On the {} day of Christmas, my true love gave to me:",
            days[day]
        );
        for gift in (0..=day).rev() {
            if day > 0 && gift == 0 {
                println!("And {}", gifts[gift]);
            } else {
                println!("{}", gifts[gift]);
            }
        }
        println!();
    }
}

fn fibonacci(n: u32) -> u64 {
    if n == 0 {
        print!("{} \n", 0);
        return 0;
    } else if n == 1 {
        print!("{} \n", 1);
        return 1;
    }

    let mut prev = 0;
    let mut curr = 1;
    for _ in 2..=n {
        let next = prev + curr;
        prev = curr;
        curr = next;
        print!("{} ", curr);
    }
    println!();
    curr
}

fn celsius_to_fahrenheit(c: f64) -> f64 {
    (c * 9.0 / 5.0) + 32.0
}

fn fahrenheit_to_celsius(f: f64) -> f64 {
    (f - 32.0) * 5.0 / 9.0
}
